package algocity.modelo.energia;

import algocity.modelo.juego.*;
import algocity.modelo.mapa.*;
import algocity.modelo.necesidades.SuperficieInvalidaException;
import algocity.modelo.zona.Construccion;
import algocity.modelo.zona.SuperficieLlano;

public class CentralElectrica
        extends Construccion {

    private final CentralElectricaTipo tipo;
    private Monetizable monedero;
    private  Mapa mapa;
    private int energiaRestante;

    public CentralElectrica(CentralElectricaTipo tipo, Mapa mapa, Monetizable monedero)  {
        this.tipo = tipo;
        energiaRestante = tipo.getCapacidadAbastecimiento();
        this.mapa = mapa;
        this.monedero = monedero;
        danioGodzilla = (float) 0.35;
    }

    public int getRango() {
        return tipo.getRango();
    };

    /**
     * Consulta la capacidad de energía inicial de la central
     * @return energía para la que la central fue diseñada
     */
    public int getCapacidadAbastecimiento() {
        return tipo.getCapacidadAbastecimiento();
    };

    // ToDo cambiar para que sólo salga ConstruccionFallidaException()
    @Override
    public void construite(Construible hectarea) throws JuegoNoIniciadoException, FueraDelMapaException, SuperficieInvalidaException, DineroInsuficienteException {

        verificarSuperficie(hectarea);
        monedero.quitarDinero(tipo.getCostoInfraestructura());

        hectarea.setConstruccion(this);

        // Energizar las manzanas cercanas
        for ( int i = 1 ; i <= tipo.getRango(); i++) {
            mapa.operarEnElRadio(i, hectarea, new OperadorEnergizador(new EnergizadorCentralElectrica(this)));
        }

        ubicacion = hectarea.getPosicion();

    }

    private void verificarSuperficie(Loteable hectarea) throws SuperficieInvalidaException {
        if ( hectarea.getSuperficie() != SuperficieLlano.getInstance()) {
            throw new SuperficieInvalidaException(hectarea.getSuperficie());
        }
    }

        public boolean esCentralElectrica() {
        return true;
    }

    public void dameEnergia(int energiaDemandada) throws EnergiaInsuficienteException {

        if (energiaDemandada > energiaRestante) {
            throw new EnergiaInsuficienteException();
        }

        energiaRestante -= energiaDemandada;

    }

    public int getCapacidadRestante() {
        return energiaRestante;
    }

    public void compensarEnergia(int energia) {
        energiaRestante += energia;
    }

    public String toString() {
        return tipo.toString();
    }

    @Override
    public void destruite() {

    }

    private class OperadorEnergizador
        extends OperadorNoDeregistrable<Hectarea> {
        private Energizador energizador;

        public OperadorEnergizador(EnergizadorCentralElectrica energizador) {
            this.energizador = energizador;
        }

        @Override
        public Boolean operar(Hectarea hectarea) {
            hectarea.ahoraTieneEnergia(energizador);

            return Boolean.TRUE;
        }
    }


    public float getReparacionSegunConstruccion() {
        return tipo.reparacionSegunConstruccion;
    }


    public boolean equals(Object otroObjeto) {
        if (this == otroObjeto) {
            return true;
        }

        if (!(otroObjeto instanceof CentralElectrica)) {
            return false;
        }

        CentralElectrica otro = (CentralElectrica) otroObjeto;

        return energiaRestante == otro.energiaRestante &&
                tipo.equals(otro.tipo) &&
                ( monedero.getDinero() ==  otro.monedero.getDinero() ) ;// FIXME issue #19
                // mapa.equals(otro.mapa) // no se puede comparar hectáreas porque da StackOverflow

    }
}
